开搞开搞
看了会od的汇编代码,查了会百度,反正就那么几条常用指令,反而更重要的是各个寄存器的作用以及保存的内容,等用到的时候再说吧,只要玩的久,迟早能学会。
开搞开搞,虽然没有系统的学习过,但是我还是感觉,实践出真理,多用,多查,学的最快了。
程序所有的代码,都是汇编形式写入的,那么就是说,我们可以直接修改汇编代码,来实现修改程序,类似网站上直接F12修改。首先打开OD,找到要修改的地方,说实话,最难的应该也就是这里了。
不过咱们可以作弊,因为有源码,直接vs打断点,查看反汇编。

那咱们尝试一下,修改错误次数,目前每次次数+1,咱们给修改成16很明显,这里有个+1给修改成+16就OK了。

记一下地址0x12267F1然后dll中试着修改一下。

注意的是,要给之前的注释掉,因为每次的偏移都是不一样的,除非没有修改过exe。不过很可惜,我这边修改了一下提示内容。哈哈。代码如下:
#define CALLOFFSET (0x12267F1)
VOID ModMemory()
{
BYTE modcode[3] = { 0 };
modcode[0] = 0x83;
modcode[1] = 0xC0;
modcode[2] = 0x10;
//覆盖式写入
if (WriteProcessMemory(GetCurrentProcess(), (LPVOID)(CALLOFFSET), modcode, 3, NULL) == 0) {
MessageBox(NULL, "写入内存失败", 0, 0);
return;
}
}
F3试试看


果然没问题。vs调试一下看看

可以看到vs中的反汇编也成功的被修改。
让软件忽略输入内容
要实现这个功能,那么就需要覆盖其中一段代码,让他调用自己的功能。大致想法如下:

查看反汇编,看到这个调用系统函数的,刚好是5个字节,那么就给这个替换掉。

DWORD peax = 0;
// 指向了需要修改的地址
// 回跳地址就是这个地址+5
// 调用GetDlgItemText的地址
DWORD GetDlgItemTextAddr = 0x00A1681E;
DWORD dwBack = GetDlgItemTextAddr + 5;
char* pStr = NULL;
DWORD dwBuffAddr = 0;
void __declspec(naked) myfun()
{
__asm
{
mov peax, eax
}
// eax 中保存了一个指针 这个指针指向了字符串的缓冲区
dwBuffAddr = *(DWORD*)(peax);
pStr = (char*)(dwBuffAddr);
//pStr = *pStr;
memmove(pStr, "123\0", 4);
// 跳转回原来的逻辑
__asm
{
add esp, 0x8
jmp dwBack
}
};
int OnInit()
{
MessageBox(0, "成功潜入敌人内部!", "报告主人", NULL);
HANDLE hand = GetModuleHandle("login.exe");
if (!hand)
{
MessageBox(0, "查找主句柄失败!", "报告主人", NULL);
return 0;
}
// 变量区从某个区后面进行偏移
//ModCount((DWORD)hand + CALLOFFSET)
// 代码区地址从0开始偏移
//ModMemory(CALLOFFSET);
//
ModMemory2(GetDlgItemTextAddr);
return 0;
}
随便输入一下试试看。

果然已经替换掉了。对了,login.exe代码改了一下提示,现在代码如下:
void CloginDlg::OnBnClickedOk()
{
m_nCount++;
CString str;
GetDlgItemText(IDC_EDIT1, str);
if (str != _T("123"))
{
CString str2;
str2.Format("密码错误 %d 次", m_nCount);
MessageBox(str2);
return ;
}
CString str3;
str3.Format("密码验证通过,恭喜你成功登陆你输入的密码是[%s]", str);
MessageBox(str3);
return;
// TODO: 在此添加控件通知处理程序代码
CDialogEx::OnOK();
}
这个不够高级。下面就来尝试一下,昨天说的,调用软件的功能。
hook直接调用软件的功能
按照前面的知识,感觉调用软件的功能就比较简单了。为了降低难度,咱们自己写一个函数。
void ShowMessagebox(int nID)
{
CString str;
str.Format("这里是弹窗%d", nID);
MessageBox(0, str, "报告主人", 0);
}
void CloginDlg::OnBnClickedCancel()
{
ShowMessagebox(255);
// TODO: 在此添加控件通知处理程序代码
CDialogEx::OnCancel();
}
在取消按钮中调用一下。

看一下反汇编。

记录这个函数的地址,然后再注入的时候调用一下。
DWORD dwOnOKaddr = 0x0F2DC7E;
// 调用软件的功能
void CallFunction()
{
__asm
{
push 123
call dwOnOKaddr
add esp,0x4
}
}
int OnInit()
{
MessageBox(0, "成功潜入敌人内部!", "报告主人", NULL);
HANDLE hand = GetModuleHandle("login.exe");
if (!hand)
{
MessageBox(0, "查找主句柄失败!", "报告主人", NULL);
return 0;
}
CallFunction();
return 0;
}
F3试一下。直接就弹出来了,说明没问题。

研究到此为止,我感觉我可以去找个工作了,嘿嘿。
Comments | NOTHING